package com.glq1218.file.service.impl;

import com.glq1218.file.service.CosService;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.qcloud.cos.internal.Constants.MB;

/**
 * @author glq1218
 * @description 腾讯云对象存储文件上传
 * @since 2023/4/27 16:56
 */
@Slf4j
@Service("cosService")
@RequiredArgsConstructor
public class CosServiceImpl implements CosService {
    @Value("${tencent.cos.secretId}")
    private String secretId;
    @Value("${tencent.cos.secretKey}")
    private String secretKey;
    /**
     * 桶名称
     */
    @Value("${tencent.cos.bucketName}")
    private String bucketName;
    @Value("${tencent.cos.region}")
    private String region;

    private static final Integer FILE_MAX_SIZE = 5;

    @Override
    public String uploadFile(MultipartFile file) {
        return uploadFile(file, FILE_MAX_SIZE);
    }

    @Override
    public String uploadFile(MultipartFile file, long maxSize) {
        long fileSize = file.getSize();
        if (fileSize > maxSize * MB) {
            log.warn("用户上传了一个{}MB的文件，超过了设定的{}MB，以阻止其上传，为的就是省钱", fileSize, maxSize);
            throw new RuntimeException("上传的文件超过规定值");
        }
        String fileFullName = getFileFullName(file);
        InputStream inputStream = getInputStream(file);
        // 初始化用户信息
        COSCredentials cosCredentials = new BasicCOSCredentials(secretId, secretKey);
        // 设置地域
        ClientConfig config = new ClientConfig(new Region(region));
        // 生成COS客户端
        COSClient cosClient = new COSClient(cosCredentials, config);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        // 设置流的大小
        objectMetadata.setContentLength(file.getSize());
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileFullName, inputStream, objectMetadata);
        // 多线程后台上传文件到COS
        ThreadFactory threadFactory = new DefaultThreadFactory("cos");
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                10,
                20,
                10,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(5), threadFactory);
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                cosClient.putObject(putObjectRequest);
            }
        });
        String url = "https://leasing-platform-1300871592.cos.ap-beijing.myqcloud.com/";
        return url + fileFullName;
    }

    /**
     * 获取InputStream
     *
     * @param file 前台传入的文件
     */
    private InputStream getInputStream(MultipartFile file) {
        InputStream inputStream = null;
        try {
            inputStream = new BufferedInputStream(file.getInputStream());
        } catch (IOException e) {
            log.error("用户上传文件发生了IO异常");
            throw new RuntimeException(e);
        }
        return inputStream;
    }

    private String getFileFullName(MultipartFile file) {
        String prefix = UUID.randomUUID().toString().replace("-", "");
        String filename = file.getOriginalFilename();
        assert filename != null;
        String suffix = filename.substring(filename.lastIndexOf("."));
        return prefix + suffix;
    }
}
